package com.starry.push.netty.websocket;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.starry.push.netty.domain.LogWsConnect;
import com.starry.push.netty.service.LogWsConnectService;
import com.starry.push.netty.util.SpringUtils;
import com.starry.push.netty.vo.WsResponse;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

import static io.netty.handler.codec.stomp.StompHeaders.HEART_BEAT;

/**
 * @author WuChao
 * @version 1.0
 * @date 2020/11/3 12:04
 */
@Slf4j
public class HeartBeatHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {
                log.info("进入读空闲，本实例当前连接数：{}", WebSocketHandler.channelGroup.size());
//                ctx.writeAndFlush(new TextWebSocketFrame(HEART_BEAT.toString())).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
            } else if (event.state() == IdleState.WRITER_IDLE) {
                //写空闲，不做处理
                log.info("进入写空闲，本实例当前连接数：{}",WebSocketHandler.channelGroup.size());
            } else if (event.state() == IdleState.ALL_IDLE) {
                //关闭channel
                Channel channel = ctx.channel();
                channel.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(WsResponse.error("长时间无心跳,断开链接"))));
                channel.close();
                //更新数据库客户端链接状态
                removeWsConnectLog(channel);
            }
        }
        super.userEventTriggered(ctx, evt);
    }



    private void removeWsConnectLog(Channel channel) {
        LogWsConnectService wsConnectService = SpringUtils.getBean(LogWsConnectService.class);
        List<LogWsConnect> wsConnects = wsConnectService.list(new QueryWrapper<LogWsConnect>()
                .eq(LogWsConnect.COL_CHANNEL_ID, channel.id().asLongText()));
        if (CollectionUtils.isNotEmpty(wsConnects)) {
            wsConnects.forEach(logWsConnect -> logWsConnect.setStatus(3));
            wsConnectService.updateBatch(wsConnects);
        }
    }
}
